/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package units;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import utils.Handle;

/**
 *
 * @author jamie
 */
public class ExpressionLibrary {

    private TreeMap<Sample, List<Expression>> data_sample = new TreeMap<Sample, List<Expression>>();
    private TreeMap<Integer, List<Expression>> data_timePoints = new TreeMap<Integer, List<Expression>>();
    private TreeMap<Integer, List<Expression>> data_probe = new TreeMap<Integer, List<Expression>>();

    public void populateForSample(Sample sample, GeneLibrary geneLibrary, Handle handle) {
        String sql = "select * from expression where sampleId=" + sample.getId();
        ResultSet rs = handle.runSQLquery(sql);
        if (!data_sample.containsKey(sample)) {
            data_sample.put(sample, new ArrayList<Expression>());
        }
        try {
            while (rs.next()) {
                int probeId = rs.getInt("probeId");
                Expression de = new Expression(probeId);
                de.setGene(geneLibrary.getGene(rs.getInt("gId")));
                de.setSample(sample);
                de.setLogExp(rs.getDouble("logExp"));
                de.setTimePoint(rs.getInt("timePoint"));
                de.setpValue(rs.getDouble("pValue"));
                data_sample.get(sample).add(de);
                if (!data_timePoints.containsKey(de.getTimePoint())) {
                    data_timePoints.put(de.getTimePoint(), new ArrayList<Expression>());
                }
                if (!data_probe.containsKey(probeId)) {
                    data_probe.put(probeId, new ArrayList<Expression>());
                }
                data_timePoints.get(de.getTimePoint()).add(de);
                data_probe.get(probeId).add(de);
            }
            rs.close();
        } catch (SQLException ex) {
            Logger.getLogger(ExpressionLibrary.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void sort() {
        for (Sample s : data_sample.keySet()) {
            Collections.sort(data_sample.get(s));
        }
        for (int timePoint : data_timePoints.keySet()) {
            Collections.sort(data_timePoints.get(timePoint));
        }
        for (int probeId : data_probe.keySet()) {
            Collections.sort(data_probe.get(probeId));
        }
    }

    public void clear() {
        data_sample.clear();
        data_timePoints.clear();
    }

    public void populateForAllSamples(GeneLibrary library) {
        Handle h = Handle.getConnectedHandle("monkeys");
        List<Sample> samples = Sample.getSamples(h);
        for (Sample sample : samples) {
            populateForSample(sample, library, h);
        }
        sort();
        h.closeConnection();
    }

    public Expression getExpression(int probeId, Sample sample, int timePoint) {
        for (Expression de : data_probe.get(probeId)) {
            if (de.getSample().equals(sample) && timePoint == de.getTimePoint()) {
                return de;
            }
        }
        return null;
    }

    public List<Expression> getExpression(int probeId) {
        List<Expression> exp = new ArrayList<Expression>();
        for (Expression de : data_probe.get(probeId)) {
            exp.add(de);
        }
        return exp;
    }

    public TreeMap<Sample, Expression> getDifferentialExpression(int probeId, int timePoint) {
        TreeMap<Sample, Expression> expressions = new TreeMap<Sample, Expression>();
        for (Expression e : data_probe.get(probeId)) {
            if (e.getTimePoint() == timePoint) {
                expressions.put(e.getSample(), e);
            }
        }
        return expressions;
    }

    public TreeMap<Integer, Expression> getExpression(int probeId, Sample sample) {
        TreeMap<Integer, Expression> expressions = new TreeMap<Integer, Expression>();
        if (data_probe.containsKey(probeId)) {
            for (Expression e : data_probe.get(probeId)) {
                if (e.getSample().equals(sample)) {
                    expressions.put(e.getTimePoint(), e);
                }
            }
        }
        return expressions;
    }

    public Set<Integer> getAllProbeIds() {
        return data_probe.keySet();
    }

    public Set<Sample> getAllSamples() {
        return data_sample.keySet();
    }
}
